home *** CD-ROM | disk | FTP | other *** search
- /*
- * grafix --- cgagraf.c
- *
- * CGA graphics driver
- *
- * Written 4/87 by Scott Snyder (ssnyder@romeo.caltech.edu or @citromeo.bitnet)
- *
- */
-
- #include <dos.h>
- #include "macros.h"
- #include "grafsys.h"
-
- /* parameters that don't depend on graphics mode */
-
- #define int_cga 16
- #define cga_setmode 0
- #define cga_setpal 11
- #define mde_80bw 2
- #define mde_80co 3
- #define mde_320 4
- #define mde_640 6
- #define cid_back 0
- #define cid_pal 1
-
- #define g_linsiz 80
- #define g_oddoff 0x2000
- #define g_allmask 0xff
- #define g_bufsiz 0x4000
- #define g_screenaddr (g_obj far *)0xb8000000
- #define g_charbase (g_obj far *)0xf000fa6e
-
- /* parameters that DO depend on graphics mode */
-
- unsigned g_mode;
-
- /* these must be near so the .asm routines can get to them */
-
- unsigned NEAR g_pixbyte;
- unsigned NEAR g_bitpix;
- g_obj NEAR g_colormask;
- g_obj NEAR g_hicolormask;
- g_obj NEAR g_cmask_tbl[8];
-
- /* utility macros */
-
- #define swap(a, b) {int _tmp; _tmp=a; a=b; b=_tmp;}
- #define trimcolor(c) c &= g_colormask
- #define get_cmask(c) g_cmask_tbl[c&g_colormask]
-
- /* plot a point */
- #define plot(ptr, mask, cmask) \
- *ptr = g_xor ? ( *ptr ^ (cmask & mask)) \
- : ((*ptr & ~mask) | (cmask & mask))
-
- /* move one to right */
- #define bumpx(ptr,mask) \
- if ((mask >>= g_bitpix) == 0) { \
- mask = g_hicolormask; \
- ptr++; \
- }
-
- /* move one line */
- #define bumpy(ptr,ydir) \
- if (ptr >= (g_obj far *)(g_drawbuf+g_oddoff)) { \
- ptr-=g_oddoff; \
- if (!ydir) \
- ptr+=g_linsiz; \
- } \
- else { \
- ptr+=g_oddoff; \
- if (ydir) \
- ptr-=g_linsiz; \
- }
-
- /*****************************************************************************
- * internal utilities *
- *****************************************************************************/
-
- /* calculate byte and bit offsets in the graphics buffer for a point */
-
- STATIC void goffs(x, y, offs, pix)
- unsigned x, y, *offs, *pix;
- {
- int y0;
-
- y0 = y/2;
- *offs = y0 * g_linsiz + x/g_pixbyte + ((y0*2 != y) ? g_oddoff : 0);
- *pix = g_pixbyte - 1 - x%g_pixbyte;
- }
-
- /* fill a mask with the given color value */
-
- g_obj make_cmask(c)
- unsigned c;
- {
- int i;
- g_obj mask = 0;
-
- trimcolor(c);
- for (i=0; i<g_pixbyte; i++)
- mask = (mask<<g_bitpix) | c;
- return (mask);
- }
-
- /****************************************************************************
- * externally callable functions *
- ****************************************************************************/
-
- /* fill a region with the specified color */
-
- #ifdef __TURBOC__
- # pragma warn -rch
- #endif
- void CGA_regfill(x1, y1, x2, y2, c)
- unsigned x1, y1, x2, y2, c;
- {
- unsigned offs1, offs2, pix1, pix2, y;
- int wholeobjs;
- g_obj far *ptr1, far *ptr2;
- g_obj cmask, begmask, endmask, mask;
-
- if (y2 < y1) swap(y1, y2);
- if (x2 < x1) swap(x1, x2);
-
- goffs(x1, y1, &offs1, &pix1);
- goffs(x2, y1, &offs2, &pix2);
- wholeobjs = offs2 - offs1 - 1;
- ptr1 = g_drawbuf + offs1;
- ptr2 = g_drawbuf + offs2;
-
- cmask = get_cmask(c);
- begmask = g_allmask >> (g_pixbyte - 1 - pix1)*g_bitpix;
- endmask = g_allmask << pix2*g_bitpix;
-
- if (wholeobjs < 0) {
- mask = begmask & endmask;
- cmask &= mask;
- for (y=y1; y<=y2; y++) {
- *ptr1 = (*ptr1 & ~mask) | cmask;
- bumpy(ptr1, 0);
- }
- }
- else {
- for (y=y1; y<=y2; y++) {
- *ptr1 = (*ptr1 & ~begmask) | (cmask & begmask);
- g_fmemset(ptr1+1, cmask, wholeobjs);
- *ptr2 = (*ptr2 & ~endmask) | (cmask & endmask);
- bumpy(ptr1, 0);
- ptr2 = ptr1 + wholeobjs + 1;
- }
- }
- }
- #ifdef __TURBOC__
- # pragma warn .rch
- #endif
-
- /* fill the entire buffer with a color fast */
-
- void CGA_clearall(c)
- unsigned c;
- {
- g_fmemset(g_drawbuf, get_cmask(c), g_bufsiz);
- }
-
- /* make the drawing buffer visible */
-
- void CGA_show()
- {
- g_fmemcpy(g_physbuf, g_drawbuf, g_bufsiz);
- }
-
- /* set the background color */
-
- void CGA_setback(c)
- unsigned c;
- {
- union REGS inregs, outregs;
-
- if (g_mode == CGA_320) {
- inregs.h.ah = cga_setpal;
- inregs.h.bh = cid_back;
- inregs.h.bl = c;
- int86(int_cga, &inregs, &outregs);
- }
- }
-
- /* set the color pallette */
-
- void CGA_setpal(p, v) /* pallette register number is ignored here */
- unsigned p, v;
- {
- union REGS inregs, outregs;
-
- inregs.h.ah = cga_setpal;
- if (g_mode == 2) {
- inregs.h.bh = cid_pal;
- inregs.h.bl = p;
- }
- else {
- inregs.h.bh = cid_back;
- inregs.h.bl = v;
- }
- int86(int_cga, &inregs, &outregs);
- }
-
- /* turn on graphics mode. mode=1 is 640, mode=2 is 320 */
-
- void CGA_gopen(mode)
- unsigned mode;
- {
- union REGS inregs, outregs;
- unsigned i;
-
- g_mode = mode;
- inregs.h.ah = cga_setmode;
- inregs.h.al = (mode == CGA_640) ? mde_640 : mde_320;
- int86(int_cga, &inregs, &outregs);
- g_physbuf = g_screenaddr;
- #if defined(__TURBOC__)
- g_virtbuf = (g_obj far *)MK_FP(g_bufseg(), 0);
- #else
- FP_SEG(g_virtbuf) = g_bufseg();
- FP_OFF(g_virtbuf) = 0;
- #endif
-
- /* set up mode-dependent parameters */
-
- if (mode == 1) {
- g_xsize = 640;
- g_ysize = 200;
- g_bitpix = 1;
- g_aspect = 0.42;
- }
- else {
- g_xsize = 320;
- g_ysize = 200;
- g_bitpix = 2;
- g_aspect = 0.85;
- }
- g_pixbyte = 8/g_bitpix;
- g_xchsize = g_xsize/8;
- g_ychsize = g_ysize/8;
- g_colormask = (1<<g_bitpix) - 1;
- g_hicolormask = g_colormask << (g_pixbyte-1)*g_bitpix;
- g_colormax = g_colormask;
- g_pages = 1;
- g_curpage = 0;
-
- for (i=0; i<=g_colormask; i++)
- g_cmask_tbl[i] = make_cmask(i);
- }
-
- /* turn off graphics mode */
-
- void CGA_gclose()
- {
- union REGS inregs, outregs;
-
- inregs.h.ah = cga_setmode;
- inregs.h.al = mde_80co;
- int86(int_cga, &inregs, &outregs);
- }
-
- /* plot a point */
-
- /* This fine piece of code has now been supplanted by a weenie hunk
- of assembly.....
-
- void CGA_point(x1,y1,c)
- unsigned x1,y1,c;
- {
- long p;
- unsigned pixoff, offs;
- g_obj far *ptr;
- g_obj mask, cmask;
-
- goffs(x1, y1, &offs, &pixoff);
- ptr = g_drawbuf + offs;
- cmask = get_cmask(c);
- mask = g_colormask << pixoff*g_bitpix;
- plot(ptr, mask, cmask); /* plot pt. *
- }
- */
-
- /* draw a line... */
-
- void CGA_line(x1,y1,x2,y2,c)
- unsigned x1,y1,x2,y2,c;
- {
- unsigned pixoff, offs;
- g_obj far *ptr;
- int delx,dely;
- int xyswap=0;
- int ydir=0;
- int i,ydelx;
- g_obj mask, cmask;
-
- if (x1 > x2) { /* sort into left-right order */
- register int tmp;
- tmp=x1; x1=x2; x2=tmp;
- tmp=y1; y1=y2; y2=tmp;
- }
- goffs(x1, y1, &offs, &pixoff);
- ptr = g_drawbuf+offs;
- cmask = get_cmask(c);
- mask = g_colormask << pixoff*g_bitpix;
- plot(ptr, mask, cmask); /* plot pt. */
- if (x1==x2 && y1==y2) /* handle 1 pt. correctly */
- return;
- delx=x2-x1;
- dely=y2-y1;
- if (dely < 0) { /* handle lines from up to down */
- ydir=1;
- dely=-dely;
- }
- if (abs(dely) > delx) { /* handle slopes > 1 */
- register int tmp;
- tmp=x1; x1=y1; y1=tmp;
- tmp=x2; x2=y2; y2=tmp;
- tmp=delx; delx=dely; dely=tmp;
- xyswap=1;
- }
- ydelx=0;
- for (i=1; i<=delx; i++) {
- if ((ydelx+=dely) >= delx) {
- bumpx(ptr, mask); /* bump both x & y */
- bumpy(ptr, ydir);
- ydelx-=delx;
- }
- else
- if (xyswap) /* bump x only */
- bumpy(ptr, ydir)
- else
- bumpx(ptr, mask);
- plot(ptr, mask, cmask); /* plot point, go around again */
- }
- }
-
- /* print a character. this is really kind of cheap, and can/should
- be expanded later... */
-
- #ifdef __TURBOC__
- # pragma warn -par /* TC */
- # pragma warn -rch
- #endif
- void CGA_writech(row, col, ch, c, page)
- unsigned row, col, c;
- char ch;
- int page;
- {
- unsigned x, y, pixoff, offs;
- g_obj cmask, chdat, gdat;
- g_obj far *ptr, far *pptr, far *chpt;
- int i, j, k;
-
- x = col*8; /* character is 8 X 8 */
- y = row*8;
- if (x >= g_xsize || y >= g_ysize)
- return;
- trimcolor(c);
- cmask = get_cmask(c);
- goffs(x, y, &offs, &pixoff); /* pixoff should be 0 */
- ptr = g_drawbuf + offs;
- chpt = g_charbase + 8*ch; /* pointer to character data */
- for (i=0; i<8; i++) { /* loop for each line */
- chdat = *chpt++; /* get character data */
- if (g_bitpix == 1)
- *ptr = chdat & cmask;
- else {
- pptr = ptr;
- for (j=0; j<g_bitpix; j++) { /* g_bitpix is the # of bytes per ch */
- gdat = 0;
- for (k=0; k<g_pixbyte; k++) {
- gdat = (gdat << g_bitpix) + (chdat&0x80 ? c : 0);
- chdat <<= 1;
- }
- *pptr++ = gdat;
- }
- }
- bumpy(ptr, 0);
- }
- }
- #ifdef __TURBOC__
- # pragma warn .par /* TC */
- # pragma warn .rch
- #endif
-
- /* these two thingamabobs don't do anything */
-
- #ifdef __TURBOC__
- # pragma warn -par /* TC */
- #endif
- void CGA_point_set(c)
- unsigned c;
- {
- }
- #ifdef __TURBOC__
- # pragma warn .par /* TC */
- #endif
-
- void CGA_point_res()
- {
- }
-